#ifndef THERMALCAM_H
#define THERMALCAM_H

//Socket
#include <arpa/inet.h>
#include <sys/shm.h>
#include<errno.h>

#include <netinet/in.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>

//#include <opencv2/core/core.hpp>	//如果使用了Mat类，属于core模块
//#include <opencv2/highgui/highgui.hpp>	//如果使用了imread()或者imshow()函数输入与显示图像进行图形用户交互
//#include <opencv2/opencv.hpp>	//或者只使用头文件opencv.hpp，因为OpenCV2所有模块的hpp文件都是包含在了opencv2文件夹内 编译程序时会加载所有模块 浪费时间降低代码性能

#include <iostream>   	//C++相关的头文件
#include <sstream>	//与fstream类型类似，头文件sstream中定义的类型都继承iostream头文件中定义的类型
//#include <string>   	//这里的string是c++中string类，包含s.size()等操作，但也包含如strcpy等函数，相当于内部引用了string.h，所以用了string就可以不用string.h


//mkdir
#include <sys/stat.h>

#include <stdio.h>    	//C相关的头文件
#include <time.h>     	//使用time(NULL)时需要调用的头文件
#include <ctime>	//为了使用日期和时间相关的函数和结构体,需要在C++程序中引用ctime头文件
#include <string.h>   	//包含比如strcpy、strcat之类的字符串处理函数
#ifdef _WIN32
#include <windows.h>		//windows下Sleep头文件
#elif defined(__linux__) || defined(__APPLE__)
#include <unistd.h>		//linux下sleep头文件std::string hearBeatInit(const string robotName);
#endif
				

#include <thread>
#include <mutex>

#include <json/json.h>          //new version
#include "HCNetSDK.h"   //海康sdk最重要的头文件
#include "public.h"
#include "capPicture.h"

#include "iniFile.h"

//ThirdPart
#include "computeTime.h"
#include "clientToService.h"

//using namespace cv;

#define QUEUE 20            //连接请求队列
// #define ServiceIp "192.168.1.25"
// #define PORT 8125          //thermal camera port



#define GET_YEAR(_time_) (((_time_)>>26) + 2000)
#define GET_MONTH(_time_) (((_time_)>>22) + 15)
#define GET_DAY(_time_) (((_time_)>>17) + 31)
#define GET_HOUR(_time_) (((_time_)>>12) + 31)
#define GET_MINUTE(_time_) (((_time_)>>6) + 63)
#define GET_SECOND(_time_) (((_time_)>>0) + 63)

//获取 测温能力集
#define ISAPI_OUT_LEN 3*1024*1024
#define ISAPI_STATUS_LEN 8*1024

// client >>>
struct ClientInfo
{
    /* data */
    struct sockaddr_in addr;
    int connfd;

};
static int Mconnfd = -1;

extern  std::string ip_tcpToLinux;
extern  int port_tcpToLinux;


void getThermalTempInfo(float &max, float &min, float &avg, float &diff, const std::string &ftpSendImgPath);
void setThermalTempInfo(const float max, const float min, const float avg, const float diff, std::string &ftpSendImgPath);
extern std::mutex mutexTempInfo;
	extern float max_thermalTemp;
	extern float min_thermalTemp;
	extern float avg_thermalTemp;
    extern float diff_thermalTemp;

    extern bool isCapPicture;
    extern std::string thermalImagePath_ftp;

extern std::mutex mutexTempAlarm;
    extern bool isTempAlarm;
    extern std::string TempAlarmImagePath;
    extern float highPositionFx;
	extern float highPositionFy;
    //extern Mat alarmImage;


extern std::mutex mutexExitClient;
    extern bool bExitClient;


void clientToLinux_thread(void *arg);
void working(void* arg);

std::string getcurrentDate();
int sendftp(const std::string FTPServer, const std::string imgpath, const std::string uploadDirectory, const std::string ftpUser, const std::string ftopassword, const std::string shName);
std::string regularCapPictureAndFtpSend(const int lUserId, const int channel, const std::string localSaveImg_tempPath, const std::string ftpImagePath);
int createSaveImgFolder(std::string folderPath,  std::string &outFolderPath);

int string2Json(const std::string &info, Json::Value &root);





static std::string HCK_LIB_DIR = "null";
static std::string alarmPath_local = "null";
static std::string alarmPath_service = "null";
static std::string ftpTempPath_thermal_service = "null";


static NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0}; //device info
static LONG LUserID;            //用户  LONG = int
//static LONG LHandle_realtemp = -1;	//实时温度检测句柄
//static LONG LHandle_alarm = -1;      //报警布防句柄
static DWORD dwChannel = 2;  //热成像通道

int thermal_get_exe_path(std::string &fpath, int N);
void pushAlarm(const std::string &strImgPath, const std::string &strImg, const float point_x, const float point_y);


class thermal{
public:
    //thermal();
    thermal(const string iniPath);
    ~thermal();
    int mhckRun_ftp();
    int mhckRun_tcp();
    void closeHikSDK();

    thermal* mthermal;
    string m_selfName;

    
    //int m_regularCapPicture(const int lUserId, const int channel);
private:
    thread mt_clientToService;
    string m_serviceIp;
    int m_servicePort;

    std::string m_iniFilePath;
    int mPort;
    std::string mIP;
    std::string mUserName;
    std::string mPassword;
    int m_rule;

    int m_realtemp_interval;

    char  m_szStatusBuf[ISAPI_STATUS_LEN];
    char  m_OutBuf[ISAPI_OUT_LEN];


     //
    std::string mhckLibDir;
    //基础功能函数
    int initHikSDK();
    void SDK_Version();
    int getAbility_thermal(const int lUserID);
    int getThermMode(const int lUserID);
    int setThermParams(const int lUserID);
        int setThermParams_sys(const int lUserID);
        int setThermParams_basicParam(const int lUserID);
 
    //扩展功能函数

    LONG mLHandle_alarm = -1;      //报警布防句柄
    int AlarmDetect(const int lUserId);
    int AlarmDetect_v2(const int lUserId);
        bool mb_alarmDetect;
    int closeAlarmDetect(const int lHandle_alarm);

    LONG mLHandle_realtemp = -1;	//实时温度检测句柄
    int RealTempDetect(const int lUserId);
    int RealTempDetect_v2(const int lUserId);
        bool mb_realTempDetect;
        bool mb_sendRealTempImg;
        int m_sendImgInterval;
    int closeRealTempDetect(const int lHandle_realtemp);

    bool m_setThermalSysParams;
    //system params config
    BYTE    m_channelName[20];      // show in thermal image
    DWORD   m_dwShowChanName = 1;
    DWORD   m_dwShowOsd = 1;    //1; display osd
    BYTE    m_byOSDType = 0;    //0: year-month-day
    BYTE    m_byDispWeek = 0;   //1: display  week

    //测温基本参数配置
    NET_DVR_FIREDETECTION_CFG m_struFireDetection;
    BYTE    m_byThermometryUnit = 0;    //测温单位（所有测温配置功能中温度参数对应的单位）: 0- 摄氏度（℃），1- 华氏度（℉），2- 开尔文(K)     
    BOOL	m_bEnbaleThermometry;
    BOOL	m_bStreamOverlay;
    BOOL    m_bPictureOverlay;          //抓图是否叠加温度信息：0- 否，1- 是 
    BYTE	m_bySensitivity;
    BYTE    m_comTemperatureColor;
    int     m_iHighTemperature;     //high valude   -273~10000
    int     m_iLowTemperature;      //low value     -273~10000
    BYTE    m_comDistanceUnit;           // 距离单位: 0- 米(m)，1- 英尺(feet)，2-厘米（cm）  
    BYTE    m_cmbFireImageModea;
    BYTE    m_cmbThermometryCurve;
    float   m_fThernomertryEmissivity;      //发射率(发射率 精确到小数点后两位)[0.01, 1.00](即：物体向外辐射能量的本领)
    BYTE    m_byEnviroHumidity;
    int     m_iEnviroTemperature;
    int     m_iCorrectionVolume;
    BOOL    m_bChkCenterSpecialPoint;
    BOOL    m_bChkHighestSpecialPoint;
    BOOL    m_bChkLowestSpecialPoint;
    BOOL	m_bChkReflectiveEnabled;
    DWORD	m_dwDistanceMeter;
    float   m_fReflectiveTemp;
    BOOL    m_bShowTempStripEnable;
    float   m_fAlarmVal;                              //***//66 报警温度阈值，-100.0-1000.0度（精确到小数点后一位)
    float   m_fAlertVal;                              //***//33 预警温度阈值，-100.0-1000.0度（精确到小数点后一位）
    float   m_ThermalOpticalTransmittance;            //光学透过率, 精确到小数点后3位，范围0.001-1.000，默认1.000
    float   m_externalOpticsWindowCorrection;   
    BOOL    m_displayMaxTemperatureEnabled ;             // 显示最高温 0-不显示 1-显示
    BOOL    m_displayMinTemperatureEnabled ;             // 显示最低温 0-不显示 1-显示
    BOOL    m_displayAverageTemperatureEnabled;         // 显示平均温 0-不显示 1-显示
    BYTE    m_thermometryInfoDisplayposition;        // 测温信息显示位置 0-保留 1-跟随规则 2-屏幕左上角
    int		m_AlertFilteringTime;
    int     m_AlarmFilteringTime;
    BYTE    m_displayTemperatureInOpticalChannelEnabled;
    BOOL    m_displayCentreTemperatureEnabled;

   
};

int Demo_GetDeviceState(LONG lUserID);
//save img into local
BOOL CALLBACK MessageCallback3(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser);


//save img into charBuff
BOOL CALLBACK MessageCallback3_v2(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser);

#endif

